<script setup lang='ts'>
import type { PlusFormGroupRow } from 'plus-pro-components'
import type { VxeGridProps, VxeTableInstance } from 'vxe-table'

import { CirclePlus } from '@element-plus/icons-vue'
import {
    useAddEnterpriseFactory,
    useEditEnterpriseFactory,
    useGetCategory,
    useGetCity,
    useGetEnterpriseFactoryDetail,
    useGetProvince,
} from '@fl/api/supplier'
import { SearchTable } from '@fl/components'
import SubmitBtn from '@fl/components/submit-btn.vue'
import { cascaderValueToString, treeFindLabel } from '@fl/utils/tree'
import { cloneDeep } from 'lodash-es'

import { certificationSystemOptions, relationTypeOptions } from './constant'

const id = defineModel<string>('id', { required: true })
const visible = defineModel<boolean>('visible', { required: true })

const initialState = {
    jcFactoryOutputParamList: [],
} as any
const state = ref(cloneDeep(initialState))

const isEdit = computed(() => !!id.value)
const dialogTitle = computed(() => isEdit.value ? '编辑工厂信息' : '新增工厂信息')
const getCityParams = computed(() => state.value.provinceCode)

const { data: enterpriseFactoryDetailData, isLoading: isGetEnterpriseFactoryDetailLoading } = useGetEnterpriseFactoryDetail(id)
const { data: provinceData, isLoading: isGetProvinceLoading } = useGetProvince()
const { data: cityData } = useGetCity(getCityParams)
const { data: categoryData, isLoading: isGetCategoryLoading } = useGetCategory()
const { isPending: isAddEnterpriseFactoryPending, mutate: addEnterpriseFactory } = useAddEnterpriseFactory()
const { isPending: isEditEnterpriseFactoryPending, mutate: editEnterpriseFactory } = useEditEnterpriseFactory()

// #region Form
const formRef = ref()
const isFormLoading = computed(() =>
    isGetProvinceLoading.value
    || isGetCategoryLoading.value
    || (isEdit.value && isGetEnterpriseFactoryDetailLoading.value),
)
const isSubmitLoading = computed(() => isEdit.value ? isEditEnterpriseFactoryPending.value : isAddEnterpriseFactoryPending.value)

const group: PlusFormGroupRow[] = [{
    columns: [
        {
            colProps: {
                span: 12,
            },
            fieldProps: {
                maxlength: 20,
                onChange: (value: string) => { state.value.name = value.replace(/\s+/g, '') },
                showWordLimit: true,
            },
            label: '工厂名称',
            prop: 'name',
            valueType: 'copy',
        },
        {
            colProps: {
                span: 12,
            },
            label: '工厂地址',
            prop: 'factoryAddress',
        },
        {
            colProps: {
                span: 12,
            },
            fieldProps: {
                onChange: (value: string) => {
                    state.value.employees = Number.parseInt(value)
                },
                type: 'number',
            },
            label: '工厂人数',
            prop: 'employees',
        },
        {
            colProps: {
                span: 12,
            },
            hasLabel: false,
            prop: 'address',
        },
        {
            colProps: {
                span: 12,
            },
            label: '工厂年产值',
            prop: 'annualOutputValue',
            valueType: 'copy',
        },
        {
            colProps: {
                span: 12,
            },
            label: '工厂联系人',
            prop: 'contactName',
            valueType: 'copy',
        },
        {
            colProps: {
                span: 12,
            },
            label: '社会信用代码',
            prop: 'socialCreditCode',
            valueType: 'copy',
        },
        {
            colProps: {
                span: 12,
            },
            label: '联系人手机',
            prop: 'contactMobile',
            valueType: 'copy',
        },
        {
            colProps: {
                span: 12,
            },
            label: '与公司关系',
            options: relationTypeOptions,
            prop: 'relationType',
            valueType: 'select',
        },
        {
            label: '工厂体系认证',
            options: certificationSystemOptions,
            prop: 'certificationSystem',
            valueType: 'checkbox',
        },
    ],
    title: '工厂信息',
}, {
    columns: [
        {
            colProps: {
                span: 24,
            },
            hasLabel: false,
            prop: 'productList',
        },
    ],
    title: '工厂产品信息',
}]

const rules = {
    contactMobile: [
        {
            required: true,
            trigger: 'change',
            validator: (_rule: any, value: any, callback: any) => {
                if (!value || value.length !== 11) {
                    callback(new Error('请输入11位联系人手机号码'))
                }
                else {
                    callback()
                }
            },
        },
    ],
    contactName: [
        {
            message: '请输入工厂联系人',
            required: true,
            trigger: 'change',
        },
    ],
    factoryAddress: [
        {
            required: true,
            trigger: 'change',
            validator: (_rule: any, _value: any, callback: any) => {
                if (state.value.provinceCode && state.value.cityCode && state.value.address) {
                    callback()
                }
                else {
                    callback(new Error('请选择省市并输入工厂详细地址'))
                }
            },
        },
    ],
    name: [
        {
            message: '请输入工厂名称',
            required: true,
            trigger: 'change',
        },
    ],
    relationType: [
        {
            message: '请选择与公司关系',
            required: true,
            trigger: 'change',
        },
    ],
    socialCreditCode: [
        {
            message: '请输入社会信用代码',
            required: true,
            trigger: 'change',
        },
    ],
}

watch(() => state.value.provinceCode, (_newValue, oldValue) => {
    if (oldValue) {
        state.value.cityCode = ''
    }
})
// #endregion

// #region Table
const tableRef = ref<VxeTableInstance>()

const gridOptions = reactive<VxeGridProps>({
    columns: [
        { editRender: { autofocus: '.vxe-input--inner' }, field: 'category', slots: { default: 'category', edit: 'category_edit' }, title: '产品品类' },
        { editRender: {}, field: 'unit', slots: { edit: 'unit_edit' }, title: '单位' },
        { editRender: {}, field: 'dailyOutput', slots: { edit: 'daily_output_edit' }, title: '最大日产量' },
        { editRender: {}, field: 'lastAnnualOutput', slots: { edit: 'last_annual_output_edit' }, title: '上年产出' },
        { field: 'operation', slots: { default: 'operation' }, title: '操作', width: 200 },
    ],
    editConfig: { autoClear: false, mode: 'row', trigger: 'manual' },
    editRules: {
        category: [
            { message: '必须填写产品品类', required: true, trigger: 'change' },
        ],
        dailyOutput: [
            { message: '必须填写最大日产量', required: true, trigger: 'change' },
        ],
        unit: [
            { message: '必须填写单位', required: true, trigger: 'change' },
        ],
    },
    height: undefined,
    validConfig: {
        msgMode: 'full',
    },
})

function isActiveStatus(row: any) {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        return $table.isEditByRow(row)
    }
    return false
}
// #endregion

// #region UI Listener
async function onAddBtnClick() {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        const record = {}
        const { row: newRow } = await $table.insertAt(record, -1)
        await $table.setEditRow(newRow)
        await $table.setEditCell(newRow, 'category')
    }
}

async function onEditBtnClick(row: any) {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        await $table.setEditRow(row)
    }
}

async function onSaveEditBtnClick(_row: any) {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        await $table.clearEdit()
    }
}

async function onCancelEditBtnClick(row: any) {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        await $table.clearEdit()
        $table.revertData(row)
    }
}

function onRemoveBtnClick(row: any) {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        $table.remove(row)
    }
}

async function onSubmitBtnClick() {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        const errMap = await $table.fullValidate(true)
        if (errMap) {
            return
        }
    }
    formRef.value.handleSubmit()
}

function submit() {
    const $table = (tableRef.value as any)?.tableInstance
    const params = {
        ...state.value,
        city: treeFindLabel({ targetValue: state.value.cityCode, treeData: cityData.value! }),
        factoryAddress: undefined,
        province: treeFindLabel({ targetValue: state.value.provinceCode, treeData: provinceData.value! }),
    }
    if (isEdit.value) {
        params.id = id.value
    }

    const { tableData } = $table.getTableData()
    params.jcFactoryOutputParamList = tableData.map((item: any) => ({
        categoryFirstId: item.category?.[0],
        categoryName: item.category?.[0]
            ? treeFindLabel({
                targetValue: item.category[0],
                treeData: categoryData.value,
            })
            : '',
        categorySubId: item.category?.[1] || '',
        categorySubName: item.category?.[1]
            ? treeFindLabel({
                targetValue: item.category[1],
                treeData: categoryData.value,
            })
            : '',
        dailyOutput: item.dailyOutput,
        lastAnnualOutput: item.lastAnnualOutput,
        unit: item.unit,
    }))

    const fn = isEdit.value ? editEnterpriseFactory : addEnterpriseFactory
    fn(params, {
        onSuccess() {
            ElMessage.success('操作成功')
            closed()
        },
    })
}

function onCancelBtnClick() {
    closed()
}

function closed() {
    visible.value = false
    if (isEdit.value) {
        id.value = ''
    }
    else {
        state.value = cloneDeep(initialState)
        formRef.value.formInstance?.resetFields()
    }
}

function onAnnualOutputValueChange(value: string) {
    state.value.annualOutputValue = value.replace(
        /^(-)*(\d+)\.(\d\d\d\d\d\d).*$/,
        '$1$2.$3',
    )
}
// #endregion

watchEffect(() => {
    if (isEdit.value && enterpriseFactoryDetailData.value) {
        Object.assign(state.value, enterpriseFactoryDetailData.value, {
            jcFactoryOutputParamList: enterpriseFactoryDetailData.value.jcFactoryOutputParamList.map((item: any) => ({
                ...item,
                category: item.categorySubId ? [item.categoryFirstId, item.categorySubId] : [item.categoryFirstId],
            })),
        })
    }
})
</script>

<template>
    <PlusDialog v-model="visible"
                :title="dialogTitle"
                width="1000"
                close-on-press-escape
                @closed="closed"
    >
        <el-skeleton v-if="isFormLoading"
                     animated
        />

        <el-scrollbar v-else
                      max-height="600px"
        >
            <PlusForm ref="formRef"
                      v-model="state"
                      :group="group"
                      :label-width="120"
                      :rules="rules"
                      :has-footer="false"
                      :row-props="{ gutter: 40 }"
                      @submit="submit"
            >
                <template #plus-field-factoryAddress>
                    <div class="space-x-16 flex w-full">
                        <el-select v-model="state.provinceCode"
                                   class="flex-auto"
                                   placeholder="请选择省"
                        >
                            <el-option v-for="item in provinceData"
                                       :key="item.value"
                                       :label="item.label"
                                       :value="item.value"
                            />
                        </el-select>

                        <el-select v-model="state.cityCode"
                                   class="flex-auto"
                                   placeholder="请选择市"
                        >
                            <el-option v-for="item in cityData"
                                       :key="item.value"
                                       :label="item.label"
                                       :value="item.value"
                            />
                        </el-select>
                    </div>
                </template>

                <template #plus-field-address>
                    <el-input v-model="state.address"
                              placeholder="请输入工厂详细地址"
                              class="ml-120"
                    />
                </template>

                <template #plus-field-annualOutputValue>
                    <el-input v-model="state.annualOutputValue"
                              type="number"
                              placeholder="请输入工厂年产值"
                              @change="onAnnualOutputValueChange"
                    >
                        <template #append>
                            <span>万元</span>
                        </template>
                    </el-input>
                </template>

                <template #plus-field-productList>
                    <div class="w-full">
                        <SearchTable v-bind="gridOptions"
                                     ref="tableRef"
                                     :data="state.jcFactoryOutputParamList"
                                     row-class-name="table-row-style"
                        >
                            <template #operation="{ row }">
                                <SubmitBtn v-if="!isActiveStatus(row)"
                                           text
                                           type="primary"
                                           class="!p-4"
                                           @click="onEditBtnClick(row)"
                                >
                                    编辑
                                </SubmitBtn>

                                <SubmitBtn v-if="isActiveStatus(row)"
                                           text
                                           type="primary"
                                           class="!p-4"
                                           @click="onSaveEditBtnClick(row)"
                                >
                                    保存
                                </SubmitBtn>

                                <SubmitBtn v-if="isActiveStatus(row) && isEdit"
                                           text
                                           type="primary"
                                           class="!p-4"
                                           @click="onCancelEditBtnClick(row)"
                                >
                                    取消
                                </SubmitBtn>

                                <SubmitBtn text
                                           type="primary"
                                           class="!p-4"
                                           @click="onRemoveBtnClick(row)"
                                >
                                    删除
                                </SubmitBtn>
                            </template>

                            <template #category="{ row }">
                                {{ row.category ? cascaderValueToString(row.category, { treeData: categoryData }) : '' }}
                            </template>

                            <template #category_edit="{ row }">
                                <el-cascader v-model="row.category"
                                             :options="categoryData"
                                />
                            </template>

                            <template #unit_edit="{ row }">
                                <el-input v-model="row.unit" />
                            </template>

                            <template #daily_output_edit="{ row }">
                                <el-input v-model="row.dailyOutput"
                                          type="number"
                                />
                            </template>

                            <template #last_annual_output_edit="{ row }">
                                <el-input v-model="row.lastAnnualOutput"
                                          type="number"
                                />
                            </template>

                            <template #bottom>
                                <el-button :icon="CirclePlus"
                                           class="mt-8 w-full !border-dashed"
                                           @click="onAddBtnClick"
                                >
                                    添加
                                </el-button>
                            </template>
                        </SearchTable>
                    </div>
                </template>
            </PlusForm>
        </el-scrollbar>

        <template #footer>
            <div class="mx-auto">
                <el-button @click="onCancelBtnClick">
                    取消
                </el-button>

                <SubmitBtn type="primary"
                           :loading="isSubmitLoading"
                           @click="onSubmitBtnClick"
                >
                    提交
                </SubmitBtn>
            </div>
        </template>
    </PlusDialog>
</template>

<style lang="scss" scoped>
:deep(.body--wrapper) {
    min-height: 0 !important;
}
</style>
